home *** CD-ROM | disk | FTP | other *** search
/ Amiga CD-Sensation: Golden Games / Amiga CD-Sensation - Ausgabe 2 - Golden Games (1996)(GTI - Schatztruhe)(DE)[!].iso / Brain Activity / Rubik / source / draw.c < prev    next >
C/C++ Source or Header  |  1990-08-11  |  8KB  |  415 lines

  1. /*    drawing stuff for rubik.c     M.J.Round 3rd Feb 90    */
  2.  
  3. int twistlist[21];
  4. int x1,y1,x2,y2,x3,y3;
  5.  
  6. char tr [120] =            /*    transformations for 90 degree side rotates    */
  7.     {
  8.     0,2,8,6,
  9.     1,5,7,3,
  10.     18,45,29,42,
  11.     19,48,28,39,
  12.     20,51,27,36,
  13.     
  14.     9,11,17,15,
  15.     10,14,16,12,
  16.     24,47,35,44,
  17.     25,50,34,41,
  18.     26,53,33,38,
  19.     
  20.     18,20,26,24,
  21.     19,23,25,21,
  22.     0,45,11,38,
  23.     1,46,10,37,
  24.     2,47,9,36,
  25.     
  26.     27,29,35,33,
  27.     28,32,34,30,
  28.     6,51,17,44,
  29.     7,52,16,43,
  30.     8,53,15,42,
  31.     
  32.     36,38,44,42,
  33.     37,41,43,39,
  34.     18,9,33,6,
  35.     21,12,30,3,
  36.     24,15,27,0,
  37.     
  38.     45,47,53,51,
  39.     46,50,52,48,
  40.     20,11,35,8,
  41.     23,14,32,5,
  42.     26,17,29,2
  43.     };
  44.  
  45. extern struct points point;    /*    holds posn.s of all points     */
  46. extern struct points start;
  47. extern struct one_square square[56];
  48. extern struct Window *wnd1;
  49. extern struct Window *wnd2;
  50. extern struct Window *window;
  51. extern struct Screen *scr1;
  52. extern struct Screen *scr2;
  53. extern struct Screen *screen;
  54.  
  55. extern int viewdist;
  56. extern short xcent,ycent;
  57. extern short angle(short, short, unsigned short);
  58. extern unsigned short hypot (short, short);
  59. extern unsigned short scaling;
  60.  
  61. extern void roll (short);
  62. extern void yaw (short);
  63. extern void pitch (short);
  64. extern void fb (short, short);
  65. extern void bt (short, short);
  66. extern void lr (short, short);
  67.  
  68. void twist (short ident, short amount)
  69.         /*    ident = 0 to 5 for front,back,(bottom),(top),left,right    */
  70.         /*    amount = -1, +1 or +2    (90 degree twists)                */
  71.     {
  72.     short c;
  73.     unsigned short i,j,k;
  74.  
  75.     if (amount > 0)
  76.         {
  77.         for (i = 0; i<amount; i++)
  78.             {
  79.             for (j = ident * 20; j < ident * 20 + 20; j += 4)
  80.                 {
  81.                 c = (square[tr[j]]).colour;
  82.                 for (k = j; k < (j + 3); k++)
  83.                     (square[tr[k]]).colour = (square[tr[k+1]]).colour;
  84.                 (square[tr[j+3]]).colour = c;
  85.                 }
  86.             }
  87.         }
  88.     else
  89.         {
  90.         for (i = 0; i < (-amount); i++)
  91.             {
  92.             for (j = ident * 20; j < ident * 20 + 20; j += 4)
  93.                 {
  94.                 c = (square[tr[j+3]]).colour;
  95.                 for (k = j + 3; k > j; k--)
  96.                     (square[tr[k]]).colour = (square[tr[k-1]]).colour;
  97.                 (square[tr[j]]).colour = c;
  98.                 }
  99.             }
  100.         }
  101.     }
  102.     
  103. /*    return true if a square is clockwise else false */
  104. int clockwise(register int i)
  105.     {
  106.     register int d;
  107.     short x,y,ang1,ang2;
  108.     unsigned short r;
  109.  
  110.     d=(viewdist+(square[i].corner[0]->z)) << scaling;
  111.     x1 = xcent+(viewdist*square[i].corner[0]->x)/d;
  112.     y1 = ycent+(viewdist*square[i].corner[0]->y)/d;
  113.  
  114.     d=(viewdist+(square[i].corner[1]->z)) << scaling;
  115.     x2 = xcent+(viewdist*square[i].corner[1]->x)/d;
  116.     y2 = ycent+(viewdist*square[i].corner[1]->y)/d;
  117.  
  118.     d=(viewdist+(square[i].corner[2]->z)) << scaling;
  119.     x3 = xcent+(viewdist*square[i].corner[2]->x)/d;
  120.     y3 = ycent+(viewdist*square[i].corner[2]->y)/d;
  121.  
  122.     x = x2-x1;
  123.     y = y2-y1;
  124.     
  125.     ang1 = ang2 = 0;
  126.     
  127.     if (x || y)
  128.         ang1 = angle(x, y, (r = hypot (x, y)));
  129.     
  130.     x = x3-x2;
  131.     y = y3-y2;
  132.  
  133.     if (x || y)
  134.         ang2 = angle(x, y, (r = hypot (x, y)));
  135.     
  136.     d = ang1-ang2;
  137.     
  138.     if (d > 180)
  139.         d -= 360;
  140.     
  141.     if (d < -179)
  142.         d += 360;
  143.  
  144.     return (d > 0);
  145.     }
  146.  
  147. void draw_square(register int i)
  148.     {
  149.     register int d;
  150.     SetAPen (window->RPort,square[i].colour);
  151.     AreaMove (window->RPort,x1,y1);
  152.     AreaDraw (window->RPort,x2,y2);
  153.     AreaDraw (window->RPort,x3,y3);
  154.     d=(viewdist+(square[i].corner[3]->z)) << scaling;
  155.     AreaDraw
  156.         (
  157.         window->RPort,
  158.         xcent+(viewdist*square[i].corner[3]->x)/d,
  159.         ycent+(viewdist*square[i].corner[3]->y)/d
  160.         );
  161.     AreaEnd (window->RPort);
  162.     }
  163.  
  164. /*    this routine renders the cube with roll, yaw and pitch alpha, beta, gamma
  165.     if twists is non-zero, <layer> is rotated delta degrees at a time, through
  166.     <twists> 90 degree twists.
  167. */
  168. void showcube
  169.             (
  170.             short alpha, 
  171.             short beta, 
  172.             short gamma, 
  173.             short layer,
  174.             short twists,
  175.             short delta
  176.             )
  177.     {
  178.     int i,j;
  179.     short theta = 0;
  180.     
  181.     do
  182.         {
  183.         point = start;    /*    this copies the 'zeroed' cube to the workspace */
  184.  
  185.         if (twists)
  186.             {
  187.             theta += (twists > 0) ? -delta : delta;
  188.  
  189.             if ((theta <= -90) || (theta >= 90))
  190.                 {
  191.                 theta = (twists > 0) ? 1 : -1;
  192.                 twist (layer,theta);
  193.                 twists -= theta;
  194.                 theta = 0;
  195.                 }
  196.             else
  197.                 {
  198.                 switch (layer)
  199.                     {
  200.                     case 0:
  201.                     case 1:
  202.                         fb(layer,theta);
  203.                         break;
  204.                     case 2:
  205.                     case 3:
  206.                         bt((short)(layer-2),theta);
  207.                         break;
  208.                     default:
  209.                         lr((short)(layer-4),theta);
  210.                         break;
  211.                     }
  212.                 }
  213.             }
  214.  
  215.         if (alpha)
  216.             roll (alpha);
  217.         if (beta)
  218.             yaw (beta);
  219.         if (gamma)
  220.             pitch (gamma);
  221.     
  222.         SetAPen(window->RPort,7);
  223.         RectFill(window->RPort,2,10,190,198);
  224.         
  225.         if (theta == 0)
  226.             {
  227.             for (i=0; i<54; i++)
  228.                 if (clockwise(i))
  229.                     draw_square(i);
  230.                 else if ((i % 3) == 0)
  231.                     i += 2;
  232.             }
  233.         else if (clockwise(54))
  234.             {
  235.             draw_square(54);
  236.  
  237.             for (i=0; i<21; i++)
  238.                 if (clockwise(twistlist[i]))
  239.                     draw_square(twistlist[i]);
  240.                 else if ((i % 3) == 0)
  241.                     i += 2;
  242.  
  243.             j = 0;
  244.             
  245.             for (i=0; i<54; i++)
  246.                 {
  247.                 while ((j < 21) && ((twistlist[j]) < i))
  248.                     j++;
  249.                 
  250.                 if ((j > 20) || (i != twistlist[j]))
  251.                     {
  252.                     if (clockwise(i))
  253.                         draw_square(i);
  254.                     else if ((i % 3) == 0)
  255.                         i += 2;
  256.                     }
  257.                 }
  258.             }
  259.         else
  260.             {
  261.             if (clockwise(55))        /*    need this to get corners    */
  262.                 draw_square(55);
  263.             
  264.             j = 0;
  265.             
  266.             for (i=0; i<54; i++)
  267.                 {
  268.                 while ((j < 21) && ((twistlist[j]) < i))
  269.                     j++;
  270.                 
  271.                 if ((j > 20) || (i != twistlist[j]))
  272.                     {
  273.                     if (clockwise(i))
  274.                         draw_square(i);
  275.                     else if ((i % 3) == 0)
  276.                         i += 2;
  277.                     }
  278.                 }
  279.             
  280.             for (i=0; i<21; i++)
  281.                 if (clockwise(twistlist[i]))
  282.                     draw_square(twistlist[i]);
  283.                 else if ((i % 3) == 0)
  284.                     i += 2;
  285.             }
  286.  
  287.         ScreenToFront(screen);
  288.         
  289.         if (screen == scr1)
  290.             {
  291.             screen = scr2;
  292.             window = wnd2;
  293.             }
  294.         else
  295.             {
  296.             screen = scr1;
  297.             window = wnd1;
  298.             }
  299.         } while (twists);
  300.     }
  301.  
  302.  
  303. int whatsquare(int x, int y)    /*    returns square number, or -1    */
  304.     {
  305.     struct Window *viswindow;
  306.     int colour,i;
  307.     
  308.     if (y<12 || x>190)
  309.         return(-1);
  310.     
  311.     if (window == wnd1)
  312.         viswindow = wnd2;
  313.     else
  314.         viswindow = wnd1;
  315.     
  316.     for (i = 0; i < 4 && (colour = ReadPixel(viswindow->RPort,x,y)) == 0; i++)
  317.         {
  318.         switch (i)
  319.             {
  320.             case 0:
  321.                 x += 2;
  322.                 break;
  323.             case 1:
  324.                 y += 2;
  325.                 break;
  326.             case 3:
  327.                 x -= 2;
  328.                 break;
  329.             }
  330.         }        /*    find a nearby square if they click on the lines    */
  331.     
  332.     if (colour <= 0 || colour == 7)
  333.         return (-1);
  334.         
  335.     ClipBlit
  336.             (
  337.             viswindow->RPort,2,10,                /*    source posn        */
  338.             window->RPort,2,10,            /*    dest posn        */
  339.             188,188,                            /*    size            */
  340.             0xc0                                /*    direct copy        */
  341.             );
  342.     
  343.     SetAPen(window->RPort,7);
  344.     Flood (window->RPort,1,x,y);
  345.     
  346.     for (i=0; i<54; i++)
  347.         if (clockwise(i))
  348.             {
  349.             draw_square(i);
  350.             if (ReadPixel(window->RPort,x,y) != 7)
  351.                 return(i);
  352.     
  353.             }
  354.     
  355.     return (-1);
  356.     }
  357.  
  358. int paints(int x, int y, int pen)    /*    returns square number, or -1    */
  359.     {
  360.     struct Window *viswindow;
  361.     int colour,i;
  362.     
  363.     if (y<12 || x>190)
  364.         return(-1);
  365.  
  366.     if (window == wnd1)
  367.         viswindow = wnd2;
  368.     else
  369.         viswindow = wnd1;
  370.  
  371.     for (i = 0; i < 4 && (colour = ReadPixel(viswindow->RPort,x,y)) == 0; i++)
  372.         {
  373.         switch (i)
  374.             {
  375.             case 0:
  376.                 x += 2;
  377.                 break;
  378.             case 1:
  379.                 y += 2;
  380.                 break;
  381.             case 3:
  382.                 x -= 2;
  383.                 break;
  384.             }
  385.         }        /*    find a nearby square if they click on the lines    */
  386.     
  387.     if (colour <= 0 || colour == 7)
  388.         return (-1);
  389.  
  390.     SetAPen(viswindow->RPort,pen);
  391.     Flood (viswindow->RPort,1,x,y);
  392.     
  393.     return (whatsquare(x,y));
  394.     }
  395.  
  396. void findangles (short *alpha, short *beta, short *gamma)
  397.     {
  398.     short x,y,z;
  399.     
  400.     y = ((point.xyz [0] [0] [5]).y + (point.xyz [5] [5] [5]).y)/2;
  401.     z = ((point.xyz [0] [0] [5]).z + (point.xyz [5] [5] [5]).z)/2;
  402.  
  403.     pitch ((short) -(*gamma = -angle (z,y,hypot (z,y))));
  404.     
  405.     x = ((point.xyz [0] [0] [5]).x + (point.xyz [5] [5] [5]).x)/2;
  406.     z = ((point.xyz [0] [0] [5]).z + (point.xyz [5] [5] [5]).z)/2;
  407.     
  408.     yaw ((short) -(*beta = -angle (z,x,hypot (z,x))));
  409.     
  410.     x = ((point.xyz [0] [5] [0]).x + (point.xyz [5] [5] [5]).x)/2;
  411.     y = ((point.xyz [0] [5] [0]).y + (point.xyz [5] [5] [5]).y)/2;
  412.     
  413.     *alpha = -angle (y,x,hypot (y,x));
  414.     }
  415.